package com.ledi.guns.modular.ledipay.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ledi.guns.common.exception.AppCheckException;
import com.ledi.guns.common.persistence.dao.BillAlipayMapper;
import com.ledi.guns.common.persistence.dao.BillDetailMapper;
import com.ledi.guns.common.persistence.dao.BillWeixinMapper;
import com.ledi.guns.common.persistence.dao.ClassInfoMapper;
import com.ledi.guns.common.persistence.dao.UserMapper;
import com.ledi.guns.common.persistence.model.BillAlipay;
import com.ledi.guns.common.persistence.model.BillDetail;
import com.ledi.guns.common.persistence.model.BillWeixin;
import com.ledi.guns.common.persistence.model.ClassInfo;
import com.ledi.guns.common.persistence.model.User;
import com.ledi.guns.common.persistence.model.vo.BillDetailVo;
import com.ledi.guns.common.util.StringUtil;
import com.ledi.guns.core.shiro.ShiroKit;
import com.ledi.guns.core.shiro.ShiroUser;
import com.ledi.guns.core.util.DateUtil;
import com.ledi.guns.core.util.SystemConstans;
import com.ledi.guns.modular.ledipay.controller.req.billDetaile.QueryBillDetaileInfo;
import com.ledi.guns.modular.ledipay.service.IBillDetaileService;

/**
 * 账单明细Service
 *
 * @author fengshuonan
 * @Date 2017-11-30 10:48:13
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BillDetaileServiceImpl implements IBillDetaileService {

	protected final static Logger logger = LoggerFactory.getLogger(BillDetaileServiceImpl.class);
	@Autowired
	private BillDetailMapper billDetailMapper;

	@Autowired
	private ClassInfoMapper classInfoMapper;

	@Autowired
	private BillWeixinMapper billWeixinMapper;
	@Autowired
	private BillAlipayMapper billAlipayMapper;

	@Autowired
	private UserMapper userMapper;
	@Autowired
	private EduPayCenter eduPayCenter;
	@Autowired
	private EduPayWexinObserver eduPayWexinObserver;

	@Override
	public Page<BillDetailVo> findBillDetaileList(Page<BillDetailVo> page, QueryBillDetaileInfo queryBillDetaileInfo) {

		extracted(queryBillDetaileInfo);

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		Long schoolId = user.getSchoolId();
		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}
		queryBillDetaileInfo.setSchoolId(schoolId);
		queryBillDetaileInfo.setOrderBy("tbd." + queryBillDetaileInfo.getOrderBy());
		List<Integer> sendStatusList = null;
		String sendStatus = queryBillDetaileInfo.getSendStatus();
		if (!StringUtil.isBlank(sendStatus)) {
			sendStatusList = new ArrayList<Integer>();
			if ("0".equals(sendStatus)) {
				sendStatusList.add(-1);
				sendStatusList.add(3);
			} else if ("1".equals(sendStatus)) {
				sendStatusList.add(1);
				sendStatusList.add(2);
			} else if ("2".equals(sendStatus)) {
				sendStatusList.add(5);
				sendStatusList.add(6);
			} else if ("3".equals(sendStatus)) {
				sendStatusList.add(4);
			} else if ("4".equals(sendStatus)) {
				sendStatusList.add(5);
				sendStatusList.add(6);
				queryBillDetaileInfo.setPayWay(SystemConstans.PAY_WAY_ALI);
			} else if ("5".equals(sendStatus)) {
				sendStatusList.add(5);
				sendStatusList.add(6);
				queryBillDetaileInfo.setPayWay(SystemConstans.PAY_WAY_WEIXIN);
			}
		}
		queryBillDetaileInfo.setBillStatuss(sendStatusList);
		if (queryBillDetaileInfo.getPayStatus() != null) {
			switch (queryBillDetaileInfo.getPayStatus()) {
				case 0:
					queryBillDetaileInfo.setPayWay(SystemConstans.PAY_WAY_ALI);
					break;
				case 1:
					queryBillDetaileInfo.setPayWay(SystemConstans.PAY_WAY_WEIXIN);
					break;
				case 2:
					queryBillDetaileInfo.setPayWay(SystemConstans.PAY_WAY_CASH);
					break;
				case 3:
					queryBillDetaileInfo.setPayWay(SystemConstans.PAY_WAY_GIRO);
					break;
				case 4:
					queryBillDetaileInfo.setPayWay(SystemConstans.PAY_WAY_OTHER);
					break;
				default:
					break;
			}
		}
		if (!ShiroKit.isDirector()) {
			queryBillDetaileInfo.setMasterFlag(SystemConstans.NO);
			queryBillDetaileInfo.setUserId(Long.parseLong(user.getId() + ""));
		}
		List<BillDetailVo> searchResult = billDetailMapper.getBillDetailList(page, queryBillDetaileInfo.getSearch());

		for (BillDetailVo billDetailVo : searchResult) {
			if (billDetailVo.getBillId().equals(SystemConstans.BILL_SCAN_CODE)) {
				billDetailVo.setBillCreateTime(billDetailVo.getCreateTime());
				if (SystemConstans.PAY_WAY_ALI.equals(billDetailVo.getPayWay())) {
					// Date createTime = new Date(billDetailVo.getCreateTime().getTime());
					// createTime = DateUtil.addDaysToDate(createTime, 2);
					billDetailVo.setBillEndTime(DateUtil.addDaysToDate(billDetailVo.getCreateTime(), 1));
				} else if (SystemConstans.PAY_WAY_WEIXIN.equals(billDetailVo.getPayWay())) {
					// long currentTime = billDetailVo.getCreateTime().getTime() + 2 * 60 * 60 * 1000;
					billDetailVo.setBillEndTime(DateUtil.addDaysToDate(billDetailVo.getCreateTime(), 1));
				}
			}
		}
		page.setRecords(searchResult);
		return page;
	}

	@Override
	public List<ClassInfo> getClassInfo() {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		Long schoolId = user.getSchoolId();
		List<ClassInfo> selectList = classInfoMapper.selectList(
				new EntityWrapper<ClassInfo>().eq("is_delete", 0).eq("school_id", schoolId).ne("name", "-1L")
				.ne("name", ""));
		return selectList;
	}

	@Override
	public BillDetailVo findBillDetaileList(Long id) {

		BillDetailVo billDetailVo = billDetailMapper.getBillDetaileById(id);
		if (billDetailVo == null) {
			throw new AppCheckException("school.zhangdan.noteixt.code", "school.zhangdan.noteixt.message", "");
		}
		if (billDetailVo.getBillId().equals(SystemConstans.BILL_SCAN_CODE)) {
			billDetailVo.setBillCreateTime(billDetailVo.getCreateTime());
			if (SystemConstans.PAY_WAY_WEIXIN.equals(billDetailVo.getPayWay())) {
				BillWeixin billWeixin = new BillWeixin();
				billWeixin.setBillDetailId(billDetailVo.getBillDetailId());
				billWeixin = billWeixinMapper.selectOne(billWeixin);
				if (billWeixin != null) {
					billDetailVo.setAlipayOrderNo(billWeixin.getWeixinTransactionId());
					billDetailVo.setPayTime(billWeixin.getPayTime());
				}
				// long currentTime = billDetailVo.getCreateTime().getTime() + 2 * 60 * 60 * 1000;
				billDetailVo.setBillEndTime(DateUtil.addDaysToDate(billDetailVo.getCreateTime(), 1));
			} else if (SystemConstans.PAY_WAY_ALI.equals(billDetailVo.getPayWay())) {
				// Date createTime = new Date(billDetailVo.getCreateTime().getTime());
				// createTime = DateUtil.addDaysToDate(createTime, 2);
				billDetailVo.setBillEndTime(DateUtil.addDaysToDate(billDetailVo.getCreateTime(), 1));
			}
		}
		return billDetailVo;
	}

	@Override
	public void deleteBillDetaile(Long id) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		Long schoolId = user.getSchoolId();
		BillDetail billDetail = null;
		List<BillDetail> selectList = billDetailMapper.selectList(new EntityWrapper<BillDetail>()
				.eq("is_delete", 0)
				.eq("school_id", schoolId)
				.eq("id", id));
		if (selectList != null && selectList.size() > 0) {
			billDetail = selectList.get(0);
		}
		if (billDetail == null || billDetail.getIsDelete() == null || 1 == billDetail.getIsDelete()) {
			throw new AppCheckException("school.zhangdan.noteixt.code", "school.zhangdan.noteixt.message", "");
		}
		if ((billDetail.getPayWay().equals(SystemConstans.PAY_WAY_WEIXIN) ||
				billDetail.getPayWay().equals(SystemConstans.PAY_WAY_ALI)) &&
				4 != billDetail.getBillStatus()) {
			throw new AppCheckException("school.zhangdan.billDetailDetele.code",
					"school.zhangdan.billDetailDetele.message", "");
		}
		billDetail.setUpdaterId(Long.valueOf(user.getId()));
		billDetail.setUpdateTime(new Date());
		billDetail.setIsDelete(1);
		Integer integer = billDetailMapper.updateById(billDetail);
		if (integer < 1) {
			throw new AppCheckException("school.zhangdan.billDetailDetele.file.code",
					"school.zhangdan.billDetailDetele.file.message", "");
		}
	}

	@Override
	public void revokeBillDetaile(Long id) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		Long schoolId = user.getSchoolId();
		BillDetail billDetail = null;
		List<BillDetail> selectList = billDetailMapper.selectList(new EntityWrapper<BillDetail>()
				.eq("is_delete", 0)
				.eq("school_id", schoolId)
				.eq("id", id));
		if (selectList != null && selectList.size() > 0) {
			billDetail = selectList.get(0);
		}
		if (billDetail == null || billDetail.getIsDelete() == null || 1 == billDetail.getIsDelete()) {
			throw new AppCheckException("school.zhangdan.noteixt.code", "school.zhangdan.noteixt.message", "");
		}
		billDetail.setUpdaterId(Long.valueOf(user.getId()));
		billDetail.setUpdateTime(new Date());
		if (SystemConstans.BILL_STATUS_CANCEL == billDetail.getBillStatus()) {
			throw new AppCheckException("school.zhangdan.revokeDetailDetele.code",
					"school.zhangdan.revokeDetailDetele.message", "已关闭");
		} else if (SystemConstans.BILL_STATUS_PAY_SUCCESS == billDetail.getBillStatus()
				|| SystemConstans.BILL_STATUS_FINISH == billDetail.getBillStatus()) {
			throw new AppCheckException("school.zhangdan.revokeDetailDetele.code",
					"school.zhangdan.revokeDetailDetele.message", "已支付");
		} else if (SystemConstans.BILL_STATUS_UNSEND == billDetail.getBillStatus()
				|| SystemConstans.BILL_STATUS_SEND_FAIL == billDetail.getBillStatus()
				|| -1 == billDetail.getBillStatus()) {
			billDetail.setBillStatus(SystemConstans.BILL_STATUS_CANCEL);
			Integer integer = billDetailMapper.updateById(billDetail);
			if (integer < 1) {
				throw new AppCheckException("school.zhangdan.billDetailDetele.file.code",
						"school.zhangdan.billDetailDetele.file.message", "");
			}
		} else if (SystemConstans.BILL_STATUS_SEND_SUCCESS == billDetail.getBillStatus()) {
			if (SystemConstans.PAY_WAY_ALI.equals(billDetail.getPayWay())) {
				int billStatus = SystemConstans.BILL_STATUS_CANCEL;
				String comment = "手动关闭账单";
				String aliStatus = eduPayCenter.setBillDetailId(billDetail.getBillDetailId()).queryStatus();
				logger.error("=========" + aliStatus);
				if (aliStatus != null) {
					if ("PAYING".equalsIgnoreCase(aliStatus)) {
						throw new AppCheckException("school.bill.is.pay.code", "school.bill.is.pay.message");
					}
					if ("BILLING_SUCCESS".equalsIgnoreCase(aliStatus) || "PAY_SUCCESS".equalsIgnoreCase(aliStatus)) {
						billStatus = SystemConstans.BILL_STATUS_PAY_SUCCESS;
						comment = "手动扭转订单为缴费成功";
					}
					if ("NOT_PAY".equalsIgnoreCase(aliStatus)) {
						eduPayCenter.setBillDetailId(billDetail.getBillDetailId()).cancelBill();
					}
				}
				BillAlipay billAlipay = new BillAlipay();
				billAlipay.setBillDetailId(billDetail.getBillDetailId());
				billAlipay = billAlipayMapper.selectOne(billAlipay);
				billAlipay.setBillStatus(billStatus);
				billAlipay.setComment(comment);
				billAlipayMapper.updateById(billAlipay);
			} else if (SystemConstans.PAY_WAY_WEIXIN.equals(billDetail.getPayWay())) {
				eduPayWexinObserver.closeWinxinBill(billDetail.getBillDetailId(), billDetail.getSchoolId());
				BillWeixin billWeixin = new BillWeixin();
				billWeixin.setBillDetailId(billDetail.getBillDetailId());
				billWeixin = billWeixinMapper.selectOne(billWeixin);
				billWeixin.setBillStatus(SystemConstans.BILL_STATUS_CANCEL);
				billWeixin.setComment("手动关闭账单");
				billWeixinMapper.updateById(billWeixin);
			}

			billDetail.setBillStatus(SystemConstans.BILL_STATUS_CANCEL);
			Integer integer = billDetailMapper.updateById(billDetail);
			if (integer < 1) {
				throw new AppCheckException("school.zhangdan.billDetailDetele.file.code",
						"school.zhangdan.billDetailDetele.file.message", "");
			}
		} else {
			throw new AppCheckException("school.zhangdan.revokeDetailDetele.file.code",
					"school.zhangdan.billDetailDetele.file.message", "");
		}
	}

	@Override
	public void updateBillStatus(String billDetailId, int payStatus, String payWay, String buyerPayAmount) {

		BillDetail billDetail = new BillDetail();
		billDetail.setBillDetailId(billDetailId);
		billDetail = billDetailMapper.selectOne(billDetail);
		billDetail.setPayTime(new Date());
		billDetail.setPayWay(payWay);
		billDetail.setBillStatus(payStatus);
		billDetail.setTotalDetail(new BigDecimal(buyerPayAmount));
		billDetailMapper.updateById(billDetail);
	}

	@Override
	public Long saveClassInfo(String name) {

		ShiroUser currentUser = ShiroKit.getUser();
		// 校验当前用户是否被删除
		User oneUser = userMapper.selectById(currentUser.getId());
		if (!oneUser.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		Long schoolId = oneUser.getSchoolId();
		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}

		Map<String, Object> columnMap = new HashMap<String, Object>();
		columnMap.put("name", name);
		columnMap.put("school_id", schoolId);
		List<ClassInfo> selectByMap = classInfoMapper.selectByMap(columnMap);
		if (CollectionUtils.isNotEmpty(selectByMap)) {
			throw new AppCheckException("school.class.exit.code", "school.class.exit.message");
		}
		ClassInfo entity = new ClassInfo();
		entity.setSchoolId(schoolId);
		entity.setCreatorId(Long.parseLong(currentUser.getId() + ""));
		entity.setCreateTime(new Date());
		entity.setCreatorRole(oneUser.getRoleid());
		entity.setName(name);
		entity.setIsDelete(SystemConstans.NO);
		classInfoMapper.insert(entity);
		return entity.getId();
	}

	private void extracted(QueryBillDetaileInfo query) {

		if (query.getStartTime() != null) {
			query.setStartTime(DateUtil.formate(query.getStartTime(), true));
		}
		if (query.getEndTime() != null) {
			query.setEndTime(DateUtil.formate(query.getEndTime(), false));
		}
	}

}
